﻿using Lihong.Cms.Entity;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace Lihong.Cms.Data
{
    public class Repository<T>  //泛型类，T在使用时传入类型确定
        : IBaseData<T>
        where T : BaseEntity    //泛型约束，T必须是BaseEntity的子类
    {
        List<T> list = new List<T>();

        string filePath = "Data\\" + typeof(T).Name + ".json";

        public Repository()
        {
            if (File.Exists(filePath)) //先判断文件是否存在，存在才读取
            {
                string s = File.ReadAllText(filePath, Encoding.UTF8);
                list = JsonSerializer.Deserialize<List<T>>(s);
            }
        }

        public void Save()
        {
            string s = JsonSerializer.Serialize(list);
            File.WriteAllText(filePath, s, Encoding.UTF8);
        }

        public ICollection<T> GetAll()
        {
            return list;
        }

        public T Get(int id)
        {
            //linq查询
            T entity = list.FirstOrDefault(x => x.Id == id);
            return entity;
        }

        public bool Add(T entity)
        {
            bool exists = list.Any(x => x.Id == entity.Id);
            if (exists)
            {
                return false;
            }
            list.Add(entity);
            Save();
            return true;
        }

        public bool Delete(int id)
        {
            T entity = Get(id);
            bool ok = list.Remove(entity);
            Save();
            return ok;
        }

        public bool Update(T obj)
        {
            var entity = list.FirstOrDefault(x => x.Id == obj.Id);
            if (entity == null) return false;
            //entity.Name = obj.Name;
            //entity.DisplayOrder = obj.DisplayOrder;
            //entity.ParentId = obj.ParentId;


            //n.Author = u.Author;
            //n.CategoryId = u.CategoryId;
            //n.Content = u.Content;
            //n.Picture = u.Picture;
            //n.Source = u.Source;
            //n.Title = u.Title;
            //n.ViewCount = u.ViewCount;
            // 以上代码看起来很有规律，重复性很高，思考：有没有什么方式简化
            // 简化步骤：我能否获得n对象的所有属性，然后去循环这些属性
            // 得到  n.属性 = u.属性  一种循环

            Type t = obj.GetType();
            // 使用反射简化代码
            foreach (var property in t.GetProperties())
            {
                var ov = property.GetValue(obj);
                property.SetValue(entity, ov);
            }
            Save();
            return true;
        }
    }
}
